<?php
class Order extends CS_Controller
{
    function _init()
    {
        $this->load->helper(array('api', 'common', 'validation'));
        $this->load->library(array('virefyorderedit', 'aes'));
        $this->load->model('order_base_model', 'order_base');
        $this->load->model('macs_model', 'macs');
        $this->load->model('order_edit_model', 'order_edit');
        $this->load->model('machine_order_refund_model', 'machine_order_refund');
        $this->load->model('scenery_reviews_model', 'scenery_reviews');
    }

    /**
     * 景区订单列表
     */
    public function index()
    {
        $count = 20;
        $total = $this->order_base->total(array('payer_uid' => $this->uid));
        if ($total > 0) {
            $result = $this->order_base->page_list(array('payer_uid' => $this->uid), 0, $count);
            if ($result->num_rows() > 0) {
                $orderList = array();
                foreach ($result->result() as $value) {
                    $orderList[$value->pay_id][] = $value;
                }
                $data['orderList'] = $orderList;
            }
        }

        $data['more'] = $total > $count ? true : false;
        $this->load->view('scenic/order/index', $data);
    }

    /**
     * ajax 景区刷新列表
     */
    public function ajaxOrderList()
    {
        $data = array();
        $page = $this->input->post('page');
        $orderStatus = $this->input->post('type');
        $num = 20;
        $total = $this->order_base->total(array('payer_uid' => $this->uid, 'order_status' => $orderStatus));
        $result = $this->order_base->page_list(array('payer_uid' => $this->uid, 'order_status' => $orderStatus), $num * $page, $num);
        if ($result->num_rows() > 0) {
            $orderList = array();
            foreach ($result->result() as $value) {
                $orderList[$value->pay_id][] = $value;
            }
            $data['orderList'] = $orderList;
        }
        echo json_encode(
            array(
                'status'  => ($total >  ($page + 1) * $num) ? true : false,
                'html'    => $this->load->view('scenic/order/ajaxOrderList', $data, true),
                'possess' => ($total == 0) ? false : true,
                'sql'     => $this->db->last_query()
            )
        );
        exit;
    }

    /**
     * 详情
     */
    public function detail($orderId)
    {
        $result = $this->order_base->findById($orderId, $this->uid);
        if ($result->num_rows() == 0) {
            $this->error('scenic/order/index', '', '订单不存在');
        }
        $result = $result->row();
        if ($result->calculate_method ==3 && ! is_file($this->config->upload_image_path('common/ewm/', 'scenic-'.$orderId.'.png'))) {
            $data = array(
                'url'                  => $this->qrcodeEncrypt(array('order_id' => $orderId, 'sid' => $result->sid)), //二维码内容
                'errorCorrectionLevel' => 'L', //容错级别
                'matrixPointSize'      => 12, //生成图片大小
                'QR'                   => $this->config->upload_image_path('common/ewm/', 'qrcode.png'),
                'logo'                 => '', //准备好的logo图片
                'output'               => $this->config->upload_image_path('common/ewm/', 'scenic-'.$orderId.'.png')
            );
            $this->load->library('qrcode/qr_code', null, 'qr_code');
            $this->qr_code->generate($data);
        }
        $data['orderInfo'] = $result;
        $this->load->view('scenic/order/detail', $data);
    }

    /**
     * 按交易 支付的详情
     */
    public function payDetail($payId)
    {
        $result = $this->order_base->findByPayId($payId);
        if ($result->num_rows() == 0) {
            $this->error('scenic/order/index', '', '交易编码不存在');
        }
        $result = $result->result();
        if ($result[0]->calculate_method == 3 && ! is_file($this->config->upload_image_path('common/ewm/', 'scenic-payid-'.$payId.'.png'))) {
            $data = array(
                'url'                  => $this->qrcodeEncrypt(array('pay_id' => $payId, 'sid' => $result->sid)), //二维码内容
                'errorCorrectionLevel' => 'L', //容错级别
                'matrixPointSize'      => 12, //生成图片大小
                'QR'                   => $this->config->upload_image_path('common/ewm/','qrcode.png'),
                'logo'                 => '', //准备好的logo图片
                'output'               => $this->config->upload_image_path('common/ewm/', 'scenic-payid-'.$payId.'.png')
            );
            $this->load->library('qrcode/qr_code', null, 'qr_code');
            $this->qr_code->generate($data);
        }

        $data['orderList'] = $result;
        $this->load->view('scenic/order/payDetail', $data);
    }

    /**
     * 获取二维码路径
     */
    public function getQrcode()
    {
        $type = $this->input->get('type', true);
        $id = $this->input->get('id', true);

        $result = '';
        $qrcodeName = '';
        $key = '';
        if ( ! is_numeric($id) || $id <= 0) {
            $this->jsonMessage('参数错误');
        }
        if ($type == 1) { //订单编号
            $result = $this->order_base->findById($id, $this->uid);
            $qrcodeName = 'scenic-'.$id.'.png';
            $key = 'order_id';
        } elseif ($type == 2) { //交易编号
            $result = $this->order_base->findByPayId($id);
            $qrcodeName = 'scenic-payid-'.$id.'.png';
            $key = 'pay_id';
        }

        if ( ! $result || $result->num_rows() == 0) {
            $this->jsonMessage('订单或交易不存在');
        }
        $result = $result->row();

        if ( ! is_file($this->config->upload_image_path('common/ewm', $qrcodeName))) {
            $data = array(
                'url'                  => $this->qrcodeEncrypt(array($key => $id, 'sid' => $result->sid)), //二维码内容
                'errorCorrectionLevel' => 'L', //容错级别
                'matrixPointSize'      => 12, //生成图片大小
                'QR'                   => $this->config->upload_image_path('qrcode.png', 'qrcode/'),
                'logo'                 => '', //准备好的logo图片
                'output'               => $this->config->upload_image_path($qrcodeName, 'qrcode/')
            );
            $this->load->library('qrcode/qr_code', null, 'qr_code');
            $this->qr_code->generate($data);
        }

        echo json_encode(
            array(
                'status'     => true,
                'imgPath'    => $this->config->show_image_url($qrcodeName, '', 'common/ewm'),
                'scenicName' => $result->goods_name,
                'useStatus'  => $result->bit_use ? '已检票' : '未检票'
            )
        );
        exit;
    }

    /**
     * 二维码加个密
     */
    private function qrcodeEncrypt($qrcode)
    {
        return $this->aes->aes128cbcEncrypt(json_encode($qrcode));
    }

    /**
     * 退票
     */
    public function refund($orderId)
    {
        $result = $this->order_base->findById($orderId, $this->uid);
        if ($result->num_rows() == 0)
        {
            $this->error('scenic/order/index', '', '订单不存在');
        }
        $data['orderInfo'] = $result->row();
        $this->load->view('scenic/order/refund', $data);
    }

    /**
     * 退票
     */
    public function ajaxRefundSubmit()
    {
        $message = $this->validateEditRefund('refund');
        $status = true;
        if($message){
            $status = false;
        }
        echo json_encode(array(
            'status'  => $status,
            'message' => $message
        ));
        exit;
    }
  

    /**
     * 修改
     */
    public function modify($orderId)
    {
        $result = $this->order_base->findById($orderId, $this->uid);
        if ($result->num_rows() == 0)
        {
            $this->error('scenic/order/index', '', '订单不存在');
        }
        $data['orderInfo'] = $result->row();
        $this->load->view('scenic/order/modify', $data);
    }
  
      /**
       * 订单修改
       */
    public function ajaxModifySubmit()
    {
        $message = $this->validateEditRefund('edit');
        $status = true;
        if($message){
            $status = false;
        }
        echo json_encode(array(
            'status'  => $status,
            'message' => $message
        ));
        exit;
    }

    /**
     * 验证订单修改和退票
     * @param unknown $operate_type 操作类别 edit-修改订单 refund-退票
     */
    private function validateEditRefund($operate_type)
    {
        $postData = $this->input->post();
        $order_id = $this->input->post('order_id');
        $order = $this->order_base->findGoodsOrder($order_id);
        if ($order->num_rows() <= 0) {
            return '订单不存在';
        }
        $order = $order->row();
        
        //验证订单修改和退款
        $message = $this->validateParams($operate_type,$postData,$order);
        if($message){
            return $message;
        }
        
        //获得修改订单和退票信息
        $goods_num_o = $order->goods_num;//原有票数
        switch ($operate_type) {
            case 'edit'://如果是修改订单操作，修改订单数量就等于查询得到的订单数量
                $plantime = strtotime($postData['plantime']);
                $sfz = $postData['sfz'];
                $goods_num_n = $order->goods_num;
                break;
            case 'refund'://如果是退票操作，现有票数等于原有票数减去退票票数
                $plantime = $order->plantime;
                $sfz = $order->sfz;
                $goods_num_n = $goods_num_o - $postData['goods_num'];
                break;
        }
        
        //计算现有金额、手续费和退票金额
        $price = bcdiv($order->amount_fee, $goods_num_o, 2);
        $n_amount_fee = bcmul($price, $goods_num_n, 2);  //剩余的金额
        $amountBack = $order->amount_fee-$n_amount_fee;  //应该退还的金额
        
        $poundage = 0;
        if ($order->pay_method != 99) { //如果不是余额支付的，退款需要收取2%的手续费
            //$poundage = bcmul($amountBack, 0.02, 2);
            $amount_back = $amountBack-bcmul($amountBack, 0.02, 2);
            $poundage = 2;
        }
        $amount_back = $amountBack;
        
        //修改订单的数组信息
        $orderEditAry = array(
            'n_num' => $goods_num_n,
            'plantime' => $plantime,
            'sfz' => $sfz,
            'n_amount_fee' => $n_amount_fee,
            'poundage' => $poundage,
            'amount_back' => $amount_back
        );
        
        //对数据库进行操作
        $this->db->trans_begin();
        $edit_id = $this->order_edit->insertInto($orderEditAry, $order);
        $update = $this->order_base->orderRefund($order->order_id);
        if ( !$edit_id || !$update || $this->db->trans_status() === FALSE ){
            $this->db->trans_rollback();
            return '数据库插入失败';
        } else {
            $this->db->trans_commit();
        }
        
        //判断是不是自动对接的产品
        $o_api_id = $order->o_api_id;
        $o_goods_id = $order->o_goods_id;
        if (!empty($o_api_id) && !empty($o_goods_id)) {
            $result = $this->isAutoAbutment($order,$operate_type,$plantime,$goods_num_n);
            if($result) {
                $error_id = $result->error_id;
                $error_msg = $result->description;
                if($error_id != 0) {
                    return $error_msg;
                }
            }
        }
        
        //判断订单是否自动审核
        if ($operate_type == 'edit' || ($operate_type == 'refund' && $order->pay_method == 188 && $order->calculate_method == 3)) {
            //自动审核订单
            $this->virefyorderedit->initialize($order_id,$edit_id,0,2,'');
            $errorAry = $this->virefyorderedit->auditSuccess();
            if ($errorAry['error_code'] != 0) {
                return $errorAry['error_msg'];
            }
        }

        /**
         * 添加记录下发给机器
         */
        if ($operate_type == 'refund') {
            $machine = $this->machine_order_refund->findByOrderId($order->order_id);
            if ($machine->num_rows() <= 0) {
                if (((int)$order->bit_wan & 2048) == 2048) {
                    $status = 2;
                } else {
                    $status = 1;
                }

                $macs = $this->macs->findGoodsMacs($order->goods_id);
                if ( $macs->num_rows() > 0 ) {
                    $macIds = array();
                    foreach ($macs->result() as $key => $value) {
                        $macIds[] = $value->mac_id;
                    }
                    if ($order->mac_ids) {
                        $macAry = unserialize($order->mac_ids);
                        if (!empty($macAry)) {
                            $macIds = array_intersect($macIds, $macAry);
                        }
                    }
                    $this->machine_order_refund->insertBatch($macIds, $order->order_id, $status);
                }
            } else {
                $this->machine_order_refund->updateStatus($order->order_id, 1);
            }
        }
        
        return null;
    }
    
    /**
     * 验证参数
     * @param unknown $operate_type $operate_type 操作类别 edit-修改订单 refund-退票
     * @param unknown $postData 接收的参数
     * @param unknown $order 查询得到的订单信息
     */
    private function validateParams($operate_type,$postData,$order)
    {
        $currentTime = time();
        
        //查询得到的数量为0
        if ($order->goods_num == 0) {
            return '订单'.$order->order_id.'已退票';
        }
        //订单未支付
        if ($order->bit_pay < 0) {
            return '订单'.$order->order_id.'未支付';
        }
        //订单已使用
        if ($order->bit_use > 0) {
            return '订单'.$order->order_id.'已使用';
        }
        //如果订单状态在退票中
        if ((128 & (int)$order->bit_opt) == 128) {
            return '已经申请退票，还未审核';//已经申请退票
        }
        //如果是淘宝订单
        if ((2048 & $order->bit_wan) == 2048) {//淘宝交易
            return '淘宝订单，请到淘宝平台申请退票';
        }
        //如果是去哪儿订单
        if ((4096 & $order->bit_wan) == 4096) {//去哪儿交易
            return '去哪儿订单，请到去哪儿平台申请退票';
        }
        //如果是OTA对接着想订单
        if ((4 & $order->bit_wan) == 4) {//OTA支付交易
            return 'OTA对接订单，请到OTA平台申请退票';
        }
        switch ($operate_type) {
            case 'edit':
                $plantime = strtotime($postData['plantime']);
                $sfz = $postData['sfz'];
                
                //如果is_edit=2,表示订单不可修改(is_edit 1-可改 2-不可改)
                if ($order->is_edit == 2) {
                    return '订单不可改';
                }
                //什么都没有修改
                if ($order->plantime == $plantime && $order->sfz == $sfz) {
                    return '订单未做任何修改';
                }
                //验证身份证
                if ($order->sfz != $sfz && !validateSfz($sfz)) {
                    return '请输入正确的身份证号码';
                }
                //验证出游日期
                if ($order->plantime != $plantime) {
                    if ($plantime < $currentTime || ($order->end_time && $plantime > $order->end_time)) {
                        return '预定时间不能小于当前时间，大于使用结束时间';
                    }
                    //提前预定时间 计划出游时间 - 提前天数 - 提前日期  < 当前时间  才可预定
                    if ($order->advance_date > 0 || $order->advance_time) {
                        //计划日期+提前时分秒  - 提前日期时间戳
                        $availableDate = strtotime($postData['plantime']. ' '. $order->advance_time) - ($order->advance_date * 60*60*24);
                        if ($currentTime > $availableDate) {
                            if ($order->advance_date > 0 && $order->advance_time) {
                                return '门票 '.$order->goods_name.' 需提前'.$order->advance_date.'天预订,并且需在'.$order->advance_time.'之前预订';
                            } elseif ( $order->advance_date > 0 ) {
                                return '门票 '.$order->goods_name.' 需提前'.$order->advance_date.'天预订';
                            } else {
                                return '门票'.$order->goods_name. '需要在每天 '. $order->advance_time.':00 之前预订';
                            }
                        }
                    }
                }
                break;
            case 'refund':
                $goods_num = $postData['goods_num'];
                
                //如果is_refund=2,表示订单不可退(is_refund 1-可退 2-不可退)
                if ($order->is_refund == 2) {
                    return '订单不可退';
                }
                //如果is_refund=1,就根据退票天数和时分来判断订单是否可退
                if ($order->is_refund == 1) {
                    $refund_day = $order->refund_day;
                    $refund_time = $order->refund_time;
                    //如果设置了退票天数或者退票时分
                    if (!empty($refund_day) || !empty($refund_time)) {
                        $refund_dayint = $refund_day * 86400;
                        $refund_dateint = $order->plantime + $refund_dayint;//可退票时间的时间戳
                        //如果没有设置退票时分
                        if (empty($refund_time)) {
                            $refund_date = date('Y-m-d 23:59',$refund_dateint);//可退票时间日期模式
                        } else {
                            $refund_date = date('Y-m-d '.$refund_time,$refund_dateint);//可退票时间日期模式
                        }
                        //申请退票时间
                        $current_refund_date = date('Y-m-d H:i');
                        //如果申请退票时间大于可退票时间
                        if ($current_refund_date > $refund_date) {
                            return '订单逾期不可退';
                        }
                    }
                }
                //验证退票数量
                if (is_int($goods_num) || $goods_num <= 0) {
                    return '订单退票数量有误';
                }
                if ($goods_num > $order->goods_num) {
                    return '订单退票数量大于订单原有数量';
                }
                //如果is_partial_refund=2,表示订单不可部分退(is_partial_refund 1-是 2-否)
                if($order->is_partial_refund == 2) {
                    //如果退票数量不等于查询到的订单数量
                    if($goods_num != $order->goods_num) {
                        return '订单不支持部分退票';
                    }
                }
                break;
        }
        //验证产品是否绑定了检票机
        $macResult = $this->macs->findBySid($order->sid);
        if ($macResult->num_rows() <= 0) {
            return $order->goods_name.'没有绑定机器';
        }
        
        $newOrderId = $this->getOrderId($order->order_id);
        $mac_ids = !empty($order->mac_ids) ? unserialize($order->mac_ids) : false;
        foreach ($macResult->result() as $value) {
            if ($mac_ids && !array_key_exists($value->mac_id,$mac_ids)) {
                continue;
            }
            if ($order->order_id > $value->order_id && $value->order_id >= $newOrderId ) {
                return '检票机未下载上一次修改订单,暂不能多次修改';
            }
        }
        
        return 0;
    }
    
    /**
     * 自动对接
     * @param unknown $order 查询到的订单信息
     * @param unknown $operate_type $operate_type 操作类别 edit-修改订单 refund-退票
     */
    private function isAutoAbutment($order,$operate_type,$plantime,$goods_num_n)
    {
        switch ($operate_type) {
            case 'edit'://修改订单
                $o_type = 16;
                $isEditNum = 0;
                $isEditPlantime = 1;
                break;
            case 'refund'://退票
                $o_type = 2;
                $isEditNum = 1;
                $isEditPlantime = 0;
                break;
        }
        
        //out_other_id_is_new字段是用来判断他网订单号(着想对接他网)是存值在other_id字段中还是out_other_id字段中
        $out_other_id_is_new = $order->out_other_id_is_new;
        if ($out_other_id_is_new == 1) {
            $out_other_id = $order->out_other_id;
        } else {
            $out_other_id = $order->other_id;
        }
        if ($out_other_id) {
            $num = $order->goods_num;
            //九天科技(票付通)接口
            if($order->o_api_id == 7) {
                //$o_type = 1;//下单
                $num = $goods_num_n;
            }
            
            //要发送
            $o_goods_id_ary = array();
            $o_api_id_ary = array();
            $o_order_id_ary = array();
            array_push($o_api_id_ary,$order->o_api_id);
            array_push($o_goods_id_ary,$order->o_goods_id);
            array_push($o_order_id_ary,$order->order_id);
            $params = array(
                'o_type' => $o_type,
                'o_api_id_ary' =>$o_api_id_ary,
                'o_goods_id_ary' => $o_goods_id_ary,
                'order_id_ary' => $o_order_id_ary,
                'num' => $num,
                'isEditNum' => $isEditNum,
                'isEditPlantime' => $isEditPlantime,
                'other_scen_id' => $order->other_scen_id,
                'out_other_id' => $out_other_id,
                'plantime' => $plantime
            );
            $curlPost = 'params='.json_encode($params);
            $url = $this->config->api_base_url.'api';//对外接口地址(用于接他网接口)
            $apiResult = getApiDynamic($curlPost,$url);
            
            /*switch ($order->o_api_id) {
                case 1: case 4: case 7:
                    $url = $this->config->www_base_url.'api/api';//对外接口地址(用于接他网接口)
                    getApiDynamic($curlPost,$url);
                    break;
                default:
                    $url = $this->config->api_base_url.'api';//对外接口地址(用于接他网接口)
                    $apiResult = getApiDynamic($curlPost,$url);
                    break;
            }*/
        }
        
        if ($apiResult) {
            $apiAry = json_decode($apiResult);
            if ($apiAry) {
                return $apiAry;
            }
        }
        
        return 0;
    }

    private function getOrderId($newOrderId)
    {
        $result = $this->order_edit->findByNewOrderId($newOrderId);
        if ($result->num_rows() <= 0) {
            return $newOrderId;
        }
        $row = $result->row();
        return $this->getOrderId($row->order_id);
    }

    /**
     * 点评
     */
    public function review($orderId)
    {
        $result = $this->order_base->findById($orderId, $this->uid);
        if ($result->num_rows() == 0) {
            $this->error('scenic/order/index', '', '订单不存在');
        }
        $orderInfo = $result->row();
        if ($orderInfo->status == 1) {
            $this->error('scenic/order/index', '', '该订单已评价');
        }
        $data['orderInfo'] = $orderInfo;
        $this->load->view('scenic/order/review', $data);
    }

    /**
     * 点评提交
     */
    public function reviewSubmit()
    {
        $postData = $this->input->post();
        $order = $this->order_base->findById($postData['order_id'], $this->uid);
        if ($order->num_rows() == 0) {
            $this->jsonMessage('订单不存在');
        }
        $order = $order->row();
        if ($order->status == 1) {
            $this->error('该订单已评价');
        }

        if (empty($postData['star']) || $postData['star'] < 1) {
            $this->jsonMessage('您还没有为星级打分');
        }

        if (strlen($postData['content']) < 15) {
            $this->jsonMessage('您写的点评至少需要15个字');
        }
        $postData['uid'] = $this->uid;
        $postData['user_name'] = $this->userName;
        
        //事务开始
        $this->db->trans_start();
        $result = $this->scenery_reviews->insertReview($postData, $order);
        $this->order_base->updateInfo(array('status' => 1), $order->order_id);
        $this->db->trans_complete();
        if ($this->db->trans_status() === FALSE) {
            $this->jsonMessage('点评失败');
        } else {
            $this->jsonMessage('');
            
        }
    }
}